package com.ruoyi.tongyan.controller;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.ruoyi.common.annotation.Anonymous;
import kong.unirest.HttpResponse;
import kong.unirest.Unirest;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;

@RestController
@RequestMapping("/coze/file")
public class CozeController {

    @Value("${coze.api-token}")
    private String token;

    @Value("${coze.base-url:https://api.coze.cn/v1}")
    private String baseUrl;

    @Value("${coze.workflow-id}")
    private String workflowId;

    private final ObjectMapper mapper = new ObjectMapper();

    @PostConstruct
    public void init() {
        // 全局超时，0=无限制
        Unirest.config()
                .connectTimeout(0)
                .socketTimeout(0);
    }

    /**
     * 上传文件并执行工作流。
     * 支持自动识别文件属于合同还是其他类型，并返回相关类型的主要信息。
     * @param file 前端上传的文件，字段名必须是 "file"
     * @return Coze 返回的最终 JSON
     */
    @Anonymous
    @PostMapping(value = "/upload-and-run", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public ResponseEntity<String> uploadAndRun(@RequestPart("file") MultipartFile file) throws Exception {
        // 1. 保存 MultipartFile 到临时文件
        File tmp = Files.createTempFile("coze-", "-" + file.getOriginalFilename()).toFile();
        try (FileOutputStream out = new FileOutputStream(tmp)) {
            StreamUtils.copy(file.getInputStream(), out);
        }

        // 2. 调用文件上传接口
        String uploadUrl = baseUrl + "/files/upload";
        HttpResponse<String> uploadResp = Unirest.post(uploadUrl)
                .header("Authorization", "Bearer " + token)
                .field("file", tmp)
                .asString();

        if (uploadResp.getStatus() != 200) {
            return ResponseEntity
                    .status(502)
                    .body("{\"error\":\"文件上传失败\",\"status\":" + uploadResp.getStatus() + "}");
        }

        // 3. 解析 file_id
        JsonNode upJson = mapper.readTree(uploadResp.getBody());
        JsonNode data = upJson.path("data");
        if (!data.has("id")) {
            return ResponseEntity
                    .status(502)
                    .body("{\"error\":\"上传返回中未包含 file_id\"}");
        }
        String fileId = data.get("id").asText();

        // 4. 调用工作流接口
        String runUrl = baseUrl + "/workflow/run";
        ObjectNode req = mapper.createObjectNode();
        // parameters.input 需要是字符串形式的 JSON
        ObjectNode params = req.putObject("parameters");
        String inputJson = mapper.writeValueAsString(
                mapper.createObjectNode().put("file_id", fileId)
        );
        params.put("file_id", inputJson);
        req.put("workflow_id", workflowId);

        HttpResponse<String> runResp = Unirest.post(runUrl)
                .header("Authorization", "Bearer " + token)
                .header("Content-Type", MediaType.APPLICATION_JSON_VALUE)
                .body(req.toString())
                .asString();

        // 5. 清理临时文件
        try {
            Files.deleteIfExists(tmp.toPath());
        } catch (IOException e) {
            System.err.println("删除临时文件失败: " + e.getMessage());
        }

// 6. 只取 data 字段
        JsonNode runJson = mapper.readTree(runResp.getBody());
        JsonNode dataNode = runJson.get("data");
        if (dataNode == null) {
            return ResponseEntity
                    .status(runResp.getStatus())
                    .contentType(MediaType.APPLICATION_JSON)
                    .body(runResp.getBody());
        }

// 7. data 本身是一个被转义的 JSON 字符串，先去掉外层转义
        String dataValue = dataNode.isTextual()
                ? dataNode.asText()
                : dataNode.toString();

// 8. 再解析 dataValue，取出其中的 topic 节点
        JsonNode dataInner = mapper.readTree(dataValue);
        JsonNode topicNode = dataInner.get("topic");
        if (topicNode == null) {
            // 如果没有 topic，则直接返回整个 data 对象
            return ResponseEntity
                    .ok()
                    .contentType(MediaType.APPLICATION_JSON)
                    .body(dataValue);
        }

// 9. 返回 topic 对象
        String topicJson = topicNode.toString();
        return ResponseEntity
                .ok()
                .contentType(MediaType.APPLICATION_JSON)
                .body(topicJson);

    }
}
